/*
 * Copyright 2004 original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jbfilter.jsp;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.DynamicAttributes;
import javax.servlet.jsp.tagext.JspTag;

import org.jbfilter.core.Filter;

public class DoFilterTag<E> extends JbfilterSimpleTagSupport implements DynamicAttributes {

	private String filterId;// mandatory if not nested in FilterTag
	private final FilterDelegate<E> filterDelegate = new FilterDelegate<E>();
	
	@Override
	public void doTag() throws JspException, IOException {
		super.doTag();
		
		// if there is no filterId this tag must be nested in a filter tag
		if (filterId == null) {
			FilterTag<E> filterTag = retrieveFilterTag();
			if (filterTag == null) {
				throw new JspException(JbfilterTagAttribute.filterId + " must be set when not nested in " + FilterTag.class + ".");
			}
			// delegate filtering to filter tag
			filterDelegate.setFilterHandler(filterTag.getFilter().newFilterHandler());
			filterTag.setFilterDelegate(filterDelegate);
			return;
		}
		// do the filtering
		filterDelegate.setFilterHandler(retrieveFilter().newFilterHandler());
		filterDelegate.filter(getJspContext());
	}
	
	// retrieves the filter from the session
	private Filter<E> retrieveFilter() throws JspException {
		Object fromSession = getFromSession(filterId);
		if (fromSession == null) {
			throw new JspException("No filter found for the " + JbfilterTagAttribute.filterId + " '" + filterId + "'.");
		} 
		if (! (fromSession instanceof Filter)) {
			throw new ClassCastException("Expected : " + Filter.class + "Actual : " + fromSession.getClass());
		}
		@SuppressWarnings("unchecked")
		Filter<E> f = (Filter<E>)fromSession;
		return f;
	}
	/**
	 * Retrieves the parent {@link FilterTag} if present.
	 * @return
	 * @throws JspException
	 */
	private FilterTag<E> retrieveFilterTag() throws JspException {
		JspTag parent = getParent();
		if (parent == null || !(parent instanceof FilterTag)) {
			return null;
		}
		@SuppressWarnings("unchecked")
		FilterTag<E> filterTag = (FilterTag<E>)parent;
		return filterTag;
	}

	public void setVarFilteredItems(String varFilteredItems) {
		filterDelegate.setVarFilteredItems(varFilteredItems);
	}
	public void setFilterId(String filterId) {
		this.filterId = filterId;
	}
	@Override
	public void setDynamicAttribute(String uri, String localName, Object value) throws JspException {
		filterDelegate.setDynamicAttribute(uri, localName, value);
	}
	public void setScope(String scopeAsString) throws JspException {
		filterDelegate.setScope(scopeAsString);
	}
	
}
